#ifndef __CO_CLASS_BASE_H__
#define __CO_CLASS_BASE_H__

#include "non_copyable.h"
#include "ifaces_core.h"
#include "type_list.h"

#define BOSS_DECLARE_CLSID(co_class_uuid) \
  static Boss::TGuid GetCoClassId() \
  { \
    return #co_class_uuid; \
  }

#define BOSS_DECLARE_STR_CLSID(co_class_uuid) \
  static Boss::TGuid GetCoClassId() \
  { \
    return co_class_uuid; \
  }

#define BOSS_CLSID_OF(co_class) \
  co_class::GetCoClassId()

namespace Boss
{

  namespace Internal
  {

    template <typename T>
    struct InheritBaseIFacesList
      : public T::Head
      , public InheritBaseIFacesList<typename T::Tail>
    {
    };

    template <typename T>
    struct InheritBaseIFacesList<TL::TypeList<T, TL::NullType> >
      : public T
    {
    };

    template <>
    struct InheritBaseIFacesList<TL::NullType>
    {
    };

    class CoClassBase
      : private NonCopyable
    {
    public:
      virtual ~CoClassBase()
      {
      }
    };
  }

  struct ISynObj;

  template <typename T>
  class CoClassBase
    : public Internal::InheritBaseIFacesList<T>
    , virtual public Internal::CoClassBase
  {
  public:
    typedef T TBaseList;

  protected:
    virtual ISynObj& GetSynObj() const = 0;
    virtual IBase* GetThisIBase() = 0;
  };

}

#endif  // !__CO_CLASS_BASE_H__
